local ST = LibStub("AceAddon-3.0"):GetAddon("SurgeTrack", true)
local STC = ST:NewModule("SurgeTrack_Config")
local L = LibStub("AceLocale-3.0"):GetLocale(ST:GetName(), true)
local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LDB and LibStub("LibDBIcon-1.0", true)
local LSM = LibStub("LibSharedMedia-3.0", true)
local class, classFileName = UnitClass("player")
local options = {}
options.args = {}

function ST:LoadSTC()
 ST:EnableModule("SurgeTrack_Config")
 ST:DisableModule("SurgeTrack_Config")
end
function STC:OnEnable()
 STC:LoadBasic()
 ST:LoadOptions()
end
function STC:LoadBasic()

 options = {
  name = ST.NAME,
  childGroups = "tab",
  type = "group",
  args = {
   addon = {
    name = L["O_ADDON"],
    order = 1,
    type = "group",
    disabled = function() return UnitAffectingCombat("player") end,
    args = {
     enable = {
      name = L["Enable Addon"],
      type = "toggle",
      desc = L["Enable/Disable SurgeTrack."],
      order = 1,
      width = "full",
      get = function() return ST.db.profile.addon.enable end,
      set = function()
       ST:Switch()
      end,
     },
     minimap = {
      type = "toggle",
      name = L["Show Minimap Button"],
      order = 2,
      width = "full",
      get = function() return not ST.db.profile.minimap.hide end,
      set = function(_, v)
       ST.db.profile.minimap.hide = not v
       if v then LDBIcon:Show(ST.broker.name) else LDBIcon:Hide(ST.broker.name) end
      end,
      disabled = function() return not LDBIcon or IsAddOnLoaded("Broker2FuBar") or IsAddOnLoaded("FuBar") end,
     },
     LoadOptions = {
      name = L["Show Options"],
      type = "toggle",
      order = 3,
      width = "full",
      get = function() return ST.db.profile.addon.options end,
      set = function(_, v)
       ST.db.profile.addon.options = v
       ST:LoadOptions()
      end,
     },
    },
   },
  },
 }

 LibStub("AceConfig-3.0"):RegisterOptionsTable(ST.NAME, options)
 LibStub("AceConfigDialog-3.0"):AddToBlizOptions(ST.NAME, ST.NAME)
end
function ST:LoadOptions()
 if ST.db.profile.addon.options then

  options.args.general = {
   name = L["General"],
   order = 2, type = "group",
   disabled = function() return (not ST:IsEnabled()) or UnitAffectingCombat("player") end,
   args = {
    lock = {
     name = L["Lock & Hide"],
     type = "toggle",
     desc = L["Lock/Unlock Icon."],
     order = 11,
     get = function() return ST.LOCK end,
     set = function(_,v)
      ST:RootLock(v)
     end,
    },
    amount = {
     name = L["Amount"],
     type = "range",
     desc = L["Set amount."],
     min = 1,
     max = 8,
     step = 1,
     order = 21,
     disabled = function() return ST.LOCK end,
     get = function() return ST.db.profile.unit.amount end,
     set = function(_,v)
      if ( v > ST.db.profile.unit.amount ) then
       ST:CreateContainer(ST.db.profile.unit.amount+1 , v)
      else
       ST:DeleteContainer( v+1 , ST.db.profile.unit.amount )
      end
      ST.db.profile.unit.amount = v
      ST:FramePosition()
      ST:RootScale()
      ST:RootAlpha()
      ST:RootLock(false)
     end,
    },
    gap = {
     name = L["Gap"],
     type = "range",
     desc = L["Set gap."],
     min = 0,
     max = 72,
     step = 1,
     order = 31,
     disabled = function() return ST.LOCK end,
     get = function() return ST.db.profile.unit.gap end,
     set = function(_,v)
      ST.db.profile.unit.gap = v
      ST:FramePosition()
      ST:RootLock(false)
     end,
    },
    scale = {
     name = L["Scale"],
     type = "range",
     desc = L["Set scale."],
     min = 0.3,
     max = 4,
     step = 0.05,
     isPercent = true,
     order = 41,
     disabled = function() return ST.LOCK end,
     get = function() return ST.db.profile.root.scale end,
     set = function(_,v)
      ST.db.profile.root.scale = v
      ST:RootScale()
      ST:RootLock(false)
     end,
    },
    alpha = {
     name = L["Alpha"],
     type = "range",
     desc = L["Set alpha."],
     min = 0.1,
     max = 1,
     step = 0.05,
     isPercent = true,
     order = 51,
     disabled = function() return ST.LOCK end,
     get = function() return ST.db.profile.root.alpha end,
     set = function(_,v)
      ST.db.profile.root.alpha = v
      ST:RootAlpha()
      ST:RootLock(false)
     end,
    },
    array = {
     name = L["Icons Array Direction"],
     type = "select",
     order = 61,
     disabled = function() return ST.LOCK end,
     values = function() return ST.position.align end,
     get = function() return ST.db.profile.unit.array end,
     set = function(_,index)
      ST.db.profile.unit.array = index
      ST:FramePosition()
      ST:RootLock(false)
     end,
    },
    centered_align = {
     name = L["Centered Align"],
     type = "toggle",
     desc = L["O_D_ARRAY_DIRECTION"],
     order = 71,
     disabled = function() return ST.LOCK end,
     get = function() return ST.db.profile.unit.centered_align end,
     set = function(_,index)
      ST.db.profile.unit.centered_align = index
      ST:RootLock(false)
     end,
    },
    header_100 = {
     name = "",
     order = 100,
     type = "header",
    },
    name_enable = {
     name = L["Name"],
     type = "toggle",
     desc = L["Display/Hide aura name."],
     order = 111,
     get = function() return ST.db.profile.name.enable end,
     set = function(_,v)
      ST.db.profile.name.enable = v
      if v then
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].name:Show() end
      else
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].name:Hide() end
      end
     end,
    },
    name_font = {
     name = L["Name"] .. " " .. L["Font"],
     type = "select",
     order = 141,
     disabled = function() return not ST.db.profile.name.enable end,
     values = LSM:List("font"),
     get = function() return ST.db.profile.name.font end,
     set = function(_,index)
      ST.db.profile.name.font = index
      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end
     end,
    },
    name_size = {
     name = L["Name"] .. " " .. L["Size"],
     type = "range",
     min = 6,
     max = 48,
     step = 0.5,
     order = 131,
     disabled = function() return not ST.db.profile.name.enable end,
     get = function() return ST.db.profile.name.size end,
     set = function(_,v)
      ST.db.profile.name.size = v

      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end
     end,
    },
    name_position = {
     name = L["Name"] .. " " .. L["Position"],
     type = "select",
     order = 151,
     disabled = function() return not ST.db.profile.name.enable end,
     values = function() return ST.position.align end,
     get = function() return ST.db.profile.name.position end,
     set = function(_,index)
      ST.db.profile.name.position = index
      for i= 1 , ST.db.profile.unit.amount do ST:NamePosition(i) end
     end,
    },
    header_200 = {
     name = "",
     order = 200,
     type = "header",
    },
    stack_enable = {
     name = L["Stack"],
     type = "toggle",
     desc = L["Display/Hide aura stack."],
     order = 211,
     get = function() return ST.db.profile.stack.enable end,
     set = function(_,v)
      ST.db.profile.stack.enable = v
      if v then
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].stack:Show() end
      else
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].stack:Hide() end
      end
     end,
    },
    stack_font = {
     name = L["Stack"] .. " " .. L["Font"],
     type = "select",
     order = 241,
     disabled = function() return not ST.db.profile.stack.enable end,
     values = LSM:List("font"),
     get = function() return ST.db.profile.stack.font end,
     set = function(_,index)
      ST.db.profile.stack.font = index
      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end

     end,
    },
    stack_size = {
     name = L["Stack"] .. " " .. L["Size"],
     type = "range",
     min = 6,
     max = 14,
     step = 0.5,
     order = 231,
     disabled = function() return not ST.db.profile.stack.enable end,
     get = function() return ST.db.profile.stack.size end,
     set = function(_,v)
      ST.db.profile.stack.size = v
      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end
     end,
    },
    stack_one = {
     name = L["Show When Stack = 1"],
     type = "toggle",
     order = 261,
     disabled = function() return not ST.db.profile.stack.enable end,
     get = function() return ST.db.profile.stack.one end,
     set = function(_,v)
      ST.db.profile.stack.one = v
     end,
    },
    header_300 = {
     name = "",
     order = 300,
     type = "header",
    },
    cc_enable = {
     name = L["Cooldown Count"],
     type = "toggle",
     desc = L["Show/Hide cooldown count."],
     order = 311,
     get = function() return ST.db.profile.cc.enable end,
     set = function(_,v)
      ST.db.profile.cc.enable = v
      if v then
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].cc:Show() end
      else
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].cc:Hide() end
      end
     end,
    },
    cc_font = {
     name = L["Cooldown Count"] .. " " .. L["Font"],
     type = "select",
     order = 341,
     disabled = function() return not ST.db.profile.cc.enable end,
     values = LSM:List("font"),
     get = function() return ST.db.profile.cc.font end,
     set = function(_,index)
      ST.db.profile.cc.font = index
      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end

     end,
    },
    cc_size = {
     name = L["Cooldown Count"] .. " " .. L["Size"],
     type = "range",
     min = 6,
     max = 14,
     step = 0.5,
     order = 331,
     disabled = function() return not ST.db.profile.cc.enable end,
     get = function() return ST.db.profile.cc.size end,
     set = function(_,v)
      ST.db.profile.cc.size = v
      for i= 1 , ST.db.profile.unit.amount do ST:StringFont(i) end
     end,
    },
    header_400 = {
     name = "",
     order = 400,
     type = "header",
    },
    animation_overlay_glow = {
     name = "Overlay Glow" .. " " .. L["Animation"],
     type = "toggle",
     order = 410,
     get = function() return ST.db.profile.unit.animation.overlay_glow end,
     set = function(_,v)
      ST.db.profile.unit.animation.overlay_glow = v
      if v then
       for i = 1 , ST.db.profile.unit.amount do ActionButton_ShowOverlayGlow(ST.container[i].bt) end
      else
       for i = 1 , ST.db.profile.unit.amount do ActionButton_HideOverlayGlow(ST.container[i].bt) end
      end
     end,
    },
    animation_fade_on_expire = {
     name = "Fade on Expire" .. " " .. L["Animation"],
     type = "toggle",
     order = 411,
     get = function() return ST.db.profile.unit.animation.fade_on_expire end,
     set = function(_,v)
      ST.db.profile.unit.animation.fade_on_expire = v
     end,
    },
    animation_fade_in_out = {
     name = "Fade" .. " " .. L["Animation"],
     type = "toggle",
     order = 412,
     get = function() return ST.db.profile.unit.animation.fade_in_out end,
     set = function(_,v)
      ST.db.profile.unit.animation.fade_in_out = v
     end,
    },
    animation_slide = {
     name = "Slide" .. L["Animation"],
     type = "toggle",
     order = 413,
     get = function() return ST.db.profile.unit.animation.slide end,
     set = function(_,v)
      ST.db.profile.unit.animation.slide = v
     end,
    },
    cd_enable = {
     name = L["Cooldown"],
     type = "toggle",
     desc = L["Display/Hide aura cooldown."],
     order = 421,
     get = function() return ST.db.profile.cd.enable end,
     set = function(_,v)
      ST.db.profile.cd.enable = v
      if v then
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].cd:Show() end
      else
       for i = 1 , ST.db.profile.unit.amount do ST.container[i].cd:Hide() end
      end
     end,
    },
    cd_omnicc = {
     name = L["OmniCC Cooldown Count"],
     type = "toggle",
     desc = L["Use OmniCC cooldown count functions."],
     order = 431,
     disabled = function() return not (ST.db.profile.cd.enable and IsAddOnLoaded("OmniCC")) end,
     get = function() return ST.db.profile.cd.omnicc end,
     set = function(_,v)
      ST.db.profile.cd.omnicc = v
      for i = 1, ST.db.profile.unit.amount do
      ST.container[i].cd.noCooldownCount = not ST.db.profile.cd.omnicc
      end
     end,
    },
    header_500 = {
     name = "",
     order = 500,
     type = "header",
    },
    sound = {
     name = L["Play Sound"],
     type = "select",
     desc = L["O_D_PLAY_SOUND"],
     order = 511,
     width = "full",
     values = LSM:List("sound"),
     get = function() return ST.db.profile.addon.sound end,
     set = function(_,index)
       ST.db.profile.addon.sound = index
       ST:SoundNotification()
     end,
    },
    -- header_600 = {
     -- name = "",
     -- order = 600,
     -- type = "header",
    -- },
    -- flash_enable = {
     -- name = L["Flash"],
     -- type = "toggle",
     -- order = 611,
     -- get = function() return ST.db.profile.flash.enable end,
     -- set = function(_,v)
      -- ST.db.profile.flash.enable = v
     -- end,
    -- },

    -- flash_duration = {
     -- name = L["Flash"] .. " " .. L["Duration"],
     -- type = "range",
     -- min = 0.1,
     -- max = 2,
     -- step = 0.05,
     -- order = 621,
     -- disabled = function() return not ST.db.profile.flash.enable end,
     -- get = function() return ST.db.profile.flash.duration end,
     -- set = function(_,v)
      -- ST.db.profile.flash.duration = v
     -- end,
    -- },
    -- flash_background = {
     -- name = L["Flash"] .. " " .. L["Background"],
     -- type = "select",
     -- order = 631,
     -- disabled = function() return not ST.db.profile.flash.enable end,
     -- values = LSM:List("background"),
     -- get = function() return ST.db.profile.flash.background end,
     -- set = function(_,index)
       -- ST.db.profile.flash.background = index
       -- ST.flashtex:SetTexture(LSM:Fetch("background", LSM:List("background")[ST.db.profile.flash.background]))
       -- ST.flashtex:SetVertexColor(ST.db.profile.flash.color.r,ST.db.profile.flash.color.g,ST.db.profile.flash.color.b)
     -- end,
    -- },
    -- flash_color = {
     -- name = L["Flash"] .. " " .. L["Color"],
     -- type = "color",
     -- order = 641,
     -- hasAlpha = true,
     -- disabled = function() return not ST.db.profile.flash.enable end,
     -- get = function() return ST.db.profile.flash.color.r,ST.db.profile.flash.color.g,ST.db.profile.flash.color.b,ST.db.profile.flash.color.a end,
     -- set = function(_,r,g,b,a)
      -- ST.db.profile.flash.color.r = r
      -- ST.db.profile.flash.color.g = g
      -- ST.db.profile.flash.color.b = b
      -- ST.db.profile.flash.color.a = a
      -- ST.flashtex:SetVertexColor(r,g,b)
     -- end,
    -- },
    -- flash_classcolor = {
     -- name = L["Class Color"],
     -- type = "execute",
     -- order = 642,
     -- disabled = function() return not ST.db.profile.flash.enable end,
     -- func = function()
      -- ST.db.profile.flash.color.r = RAID_CLASS_COLORS[classFileName].r
      -- ST.db.profile.flash.color.g = RAID_CLASS_COLORS[classFileName].g
      -- ST.db.profile.flash.color.b = RAID_CLASS_COLORS[classFileName].b
      -- ST.flashtex:SetVertexColor(ST.db.profile.flash.color.r,ST.db.profile.flash.color.g,ST.db.profile.flash.color.b)
     -- end,
    -- },
    -- flash_test = {
     -- name = L["Test"],
     -- type = "execute",
     -- order = 651,
     -- disabled = function() return not ST.db.profile.flash.enable end,
     -- func = function()
      -- ST:doFullScrFlash()
     -- end,
    -- },
   },
  }

  options.args.aura = {
   name = L["Aura"],
   childGroups = "group",
   order = 3,
   type = "group",
   disabled = function() return not ST:IsEnabled() end,
   args = {
    class = {
     name = class,
     order = 1,
     type = "group",
     args = {
      header = {
       name = L["Select Aura to be tracked"],
       order = 100,
       type = "header",
      },
      classtable = {
       type = "multiselect",
       name = class .. " " .. L["Aura List"] ,
       order = 101,
       width = "full",
       values = ST.desc.aura.class,
       get = function(_,spellId) return ST.db.profile.aura.class[spellId] end,
       set = function(_,spellId)
        ST.db.profile.aura.class[spellId] = not ST.db.profile.aura.class[spellId]
        if ST.db.profile.aura.class[spellId] then
         ST.aura[spellId] = {track = true,}
        else
         ST:releaseItem(spellId)
         ST.aura[spellId] = {track = false,}
        end
       end,
      },
     },
    },
    common = {
     name = L["Common"],
     order = 2,
     type = "group",
     args = {
      header = {
       name = L["Select Aura to be tracked"],
       order = 100,
       type = "header",
      },
      commontable = {
       type = "multiselect",
       name = L["Common"] .. " " .. L["Aura List"] ,
       order = 102,
       width = "full",
       values = ST.desc.aura.common,
       get = function(_,spellId) return ST.db.profile.aura.common[spellId] end,
       set = function(_,spellId)
        ST.db.profile.aura.common[spellId] = not ST.db.profile.aura.common[spellId]
        if ST.db.profile.aura.common[spellId] then
         ST.aura[spellId] = {track = true,}
        else
         ST:releaseItem(spellId)
         ST.aura[spellId] = {track = false,}
        end
       end,
      },
     },
    },
    advanced = {
     name = L["O_ADVANCED"],
     order = 3,
     type = "group",
     args = {
      customtable = {
       type = "multiselect",
       name = L["Custom"] .. " " .. L["Aura List"] ,
       order = 102,
       width = "full",
       values = function()
        local auraDesc = {}
        for spellId,_ in pairs(ST.db.profile.aura.custom) do
         local auraName, auraRank, auraIcon, _, _, _, _, _, _ = GetSpellInfo(spellId)
         auraName = auraName or ""
         auraIcon = "|T".. (auraIcon or ST.IMG) .. ":0|t"
         if (not auraRank) or auraRank == "" then auraRank = "" else auraRank = "(" .. auraRank .. ")" end
         auraDesc[spellId] = auraIcon .. auraName .. auraRank
        end
        return auraDesc
       end,
       get = function(_,spellId)
        return ST.db.profile.aura.custom[spellId]
       end,
       set = function(_,spellId)
        ST.db.profile.aura.custom[spellId] = not ST.db.profile.aura.custom[spellId]
        if ST.db.profile.aura.custom[spellId] then
         ST.aura[spellId] = {track = true,}
        else
         ST:releaseItem(spellId)
         ST.aura[spellId] = {track = false,}
        end
       end,
      },
      header_add = {
       name = L["O_H_AURA_ADD"],
       order = 200,
       type = "header",
      },
      gathermode_desc = {
       name = "|cffffcc00".. "a. " .. L["Enable Gather Mode"] .."|r" ,
       type = "description",
       order = 211,
      },
      -- gathermode = {
       -- type = "toggle",
       -- name = L["Enable Gather Mode"],
       -- desc = L["O_H_AURA_ADD"],
       -- order = 212,
       -- width = "full",
       -- confirm = function()
        -- return (not ST.GATHER) and (L["Enable Gather Mode"] .."?")
       -- end,
       -- get = function()
        -- return ST.GATHER
       -- end,
       -- set = function(_, v)
        -- ST:GetModule("SurgeTrack_Aura", true):GatherMode(v)
       -- end,
      -- },
      gathermode = {
       type = "execute",
       name = L["Enable Gather Mode"],
       desc = L["O_H_AURA_ADD"],
       order = 212,
       width = "full",
       func = function()
        ST:GetModule("SurgeTrack_Aura", true):GatherMode(true)
       end,
      },
      add_spell_id = {
       name = "b. " .. L["O_H_INPUT_SPELLID"],
       order = 213,
       type = "input",
       width = "double",
       validate = function(_,spellId_string)
        if not tonumber(spellId_string) then
         return false
        elseif tonumber(spellId_string) > 100000 or tonumber(spellId_string) < 1 then
         return false
        elseif (not select(1,GetSpellLink(tonumber(spellId_string)))) or (not GetSpellInfo(tonumber(spellId_string))) then
         return false
        else
         return true
        end
       end,
       usage = "SpellId",
       confirm = function(_,spellId_string)
        return L["O_H_AURA_ADD"]..": "..select(1,GetSpellLink(tonumber(spellId_string)))
       end,
       set = function(_,spellId_string)
        ST:addCustomSpellToDb(tonumber(spellId_string))
       end,
      },
      header_remove = {
       name = L["O_H_AURA_DELETE"],
       order = 300,
       type = "header",
      },
      remove_custom_user_aura = {
       type = "execute",
       name = L["Remove All UNSELECTED aura in Custom Aura List!"],
       order = 310,
       confirm = true,
       width = "full",
       func = function()
        for spellId,selected in pairs(ST.db.profile.aura.custom) do
         if not selected then
          ST:Print(L["O_H_AURA_DELETE"]..": "..select(1,GetSpellLink(spellId)))
          ST.db.profile.aura.custom[spellId] = nil
          ST:releaseItem(spellId)
          ST.aura[spellId] = nil
         end
        end
       end,
      },
     },
    },
   },
  }

  options.args.spell = {
   name = L["Spell"],
   childGroups = "group",
   order = 5,
   type = "group",
   disabled = function() return not ST:IsEnabled() end,
   args = {
    class = {
     name = class,
     order = 1,
     type = "group",
     args = {
      header = {
       name = L["Select spell to be tracked"],
       order = 100,
       type = "header",
      },
      classtable = {
       type = "multiselect",
       name = class .. " " .. L["Spell List"] ,
       order = 101,
       width = "full",
       values = ST.desc.spell.class,
       get = function(_,spellId) return ST.db.profile.spell.class[spellId] end,
       set = function(_,spellId)
        ST.db.profile.spell.class[spellId] = not ST.db.profile.spell.class[spellId]
        if ST.db.profile.spell.class[spellId] then
         ST.spell[spellId] = false
         ST.spelldesc[select(1, GetSpellInfo(spellId))] = spellId
        else
         ST:releaseItem(spellId)
         ST.spell[spellId] = nil
         ST.spelldesc[select(1, GetSpellInfo(spellId))] = nil
        end
       end,
      },
     },
    },
   },
  }

  options.args.about = {
   name = L["O_ABOUT"],
   order = 6,
   type = "group",
   disabled = function() return not ST:IsEnabled() end,
   args = {
    about_head = {
     name = "|cffffcc00"..GetAddOnMetadata(ST.NAME,"Title").."|r",
     type = "description",
     order = 11,
    },
    about_desc = {
     name = GetAddOnMetadata(ST.NAME, "Notes").."\n",
     type = "description",
     order = 12,
    },
    vers_head = {
     name = "|cffffcc00"..L["Version"].."|r",
     type = "description",
     order = 21,
    },
    vers_desc = {
     name = GetAddOnMetadata(ST.NAME, "Version").."\n",
     type = "description",
     order = 22,
    },
    url_head = {
     name = "|cffffcc00"..L["Web Site"].."|r",
     type = "description",
     order = 31,
    },
    url_desc = {
     name = "",
     width = "full",
     get = function()
      return GetAddOnMetadata(ST.NAME, "X-website-curse")
     end,
     type = "input",
     order = 42,
    },
    tran_head = {
     name = "\n|cffffcc00"..L["O_D_HELP_TRANSLATION"].."|r",
     type = "description",
     order = 51,
    },
    tran_desc = {
     name = "",
     width = "full",
     get = function()
      return GetAddOnMetadata(ST.NAME, "X-website-curseforge")
     end,
     type = "input",
     order = 52,
    },
   },
  }

  options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(ST.db)
  options.args.profiles.disabled = function() return not ST:IsEnabled() end

 else

  options.args.general = nil
  options.args.aura = nil
  options.args.spell = nil
  options.args.about = nil
  options.args.profiles = nil

 end

 LibStub("AceConfigRegistry-3.0"):NotifyChange(ST.NAME)

end
